December 1998
"Winzip V7 KeyGen"
Win '95 PROGRAM
Win Code Reversing
 
 
by  Borna Janes
 
 
Code Reversing For Beginners 
 

 
 

Program Details
Program Name: winzip70.exe
Program Type: Win'95 unzipper
Program Location: Here
Program Size: 921 K 
 
  
Tools Used:
Softice 3.2 - Debugger
W32Dasm V8.9 - Disassembler
 
Rating
Easy ( X )  Medium (   )  Hard (    )  Pro (    )
There is a crack, a crack in everything. That's how the light gets in.


How to make Winzip V7 KeyGen

Written by Borna Janes


 
 
 
About this protection system
When Winzip is unregistred, on each startup it shows a nag screen that remind us to register program.
We can register WInzip by pressing ' Enter Registration Code' button.
Then we must enter:

Name
Registration #

On successful registration the program saves registration informations into :

 HKEY\Current_User\Software\Nico Mak Computing\Winzip\WinIni

Name                    "Borna Janes"
SN                         "FBAA149F" or "70684782"
Win32_version  "6.3-7.0"
 
 
 
 
The Essay

Program generates two valid serial numbers.

First serial contians numbers and letters (HEX format), and second serial contains only numbers (DECIMAL format).
 
Each serial number is generated with two calculation routines.
First calc routine generates first four characters and second one generates second four characters of serial.
That means that serials has eight characters!
 
Let's start...
 
When you run Winzip, you'll see nag screen that pops up.
Press ' Enter Registration Code' button and enter your handle and any random serial number.
For example here is what entered:
 
Name:                 Borna Janes
Registration  #:   998899
 
 
Press CTRL-D to pop up Softice and type bpx GetDlgItemTextA, then hit CTRL-D again to leave Softice.
 
Press 'OK' button.
Softice now breaks on GetDlgItemTextA function, hit  ' F11' to return to Winzip code and 'BD 0' for disable breakpoint .
You can now see this section of code:
 
:00408014 FF150C844600       Call dword ptr [0046840C]
:0040801A 53                 push ebx                           ;We are here
:0040801B E879160200         call 00429699
:00408020 59                 pop ecx                            ;ECX = Name
:00408021 53                 push ebx
:00408022 E89B160200         call 004296C2
:00408027 59                 pop ecx
:00408028 BE58D94700         mov esi, 0047D958
:0040802D 6A0B               push 0000000B
:0040802F 56                 push esi
:00408030 68810C0000         push 00000C81
:00408035 57                 push edi
:00408036 FF150C844600       Call dword ptr [0046840C]
:0040803C 56                 push esi
:0040803D E857160200         call 00429699
:00408042 59                 pop ecx                           ;ECX = fake serial
:00408043 56                 push esi
:00408044 E879160200         call 004296C2
:00408049 803D28D9470000     cmp byte ptr [0047D928], 00       ;Check lenth of name
:00408050 59                 pop ecx                           ;ECX = fake serial
:00408051 745F               je 004080B2                       ;If 0 then display error
:00408053 803D58D9470000     cmp byte ptr [0047D958], 00       ;Check lenth of serial
:0040805A 7456               je 004080B2                       ;If 0 then display error
:0040805C E8EAFAFFFF         call 00407B4B                     ;Create and compare serials
:00408061 85C0               test eax, eax                     ;EAX 0 = Wrong serial,   EAX 1 = Good serial
:00408063 744D               je 004080B2                       ;If wrong serial display error
:00408065 53                 push ebx
:00408066 BBB80C4700         mov ebx, 00470CB8
 
How we can see there are two calls to GetDlgItemTextA function.
One for name and one for serial. After that calls program puts locations of name and serial in ECX.
There are also two compare functions at 00408049 and 00408053.
They checks lenth of name and serial. If there is no name or serial then display error message.
For us is only important call at 0040805C witch create real and compare fake and real serial.
If number is wrong then EAX = 0 if number is good then EAX = 1.
If you anywhere inside the call at 40805C see XOR EAX,EAX it's bad because it indicates that serial is wrong!
Now press 'F10' until you step on 0040805C then press 'T ' to trace the code inside the call.
 
You'll now see this piece of code:
 
 
:00407B4B 55                 push ebp
:00407B4C 8BEC               mov ebp, esp
:00407B4E 81EC08020000       sub esp, 00000208
:00407B54 53                 push ebx
:00407B55 56                 push esi
:00407B56 33F6               xor esi, esi                       ; ESI = 0
:00407B58 803D28D9470000     cmp byte ptr [0047D928], 00        ;Check lenth of name
:00407B5F 57                 push edi
:00407B60 0F84A1000000       je 00407C07                        ;If 0 then display error
:00407B66 8D45EC             lea eax, dword ptr [ebp-14]        ;Memory location for next string
:00407B69 50                 push eax
:00407B6A 6860F44600         push 0046F460
:00407B6F E84F9CFFFF         call 004017C3                      ;Save "MuradMeraly"  to EAX
:00407B74 59                 pop ecx
:00407B75 8D85F8FDFFFF       lea eax, dword ptr [ebp+FFFFFDF8]  ;Memory location for next string
:00407B7B 59                 pop ecx                            ;ECX= "MuradMeraly"
:00407B7C BF28D94700         mov edi, 0047D928                  ;EDI = Name
:00407B81 50                 push eax
:00407B82 57                 push edi
:00407B83 E8A9020000         call 00407E31                      ;Make second copy of name
:00407B88 59                 pop ecx
:00407B89 8D85F8FDFFFF       lea eax, dword ptr [ebp+FFFFFDF8]
:00407B8F 59                 pop ecx                            ;ECX = Second copy of name